# -*- coding: utf-8 -*-

import pygame

from game import Vec2d

ALPHA_COLOR = pygame.Color(255, 0, 255)

#gui tree object
#Empty GUI note with basic interface
class Gui(object):

    LEFT = "ALIGN LEFT"
    RIGHT = "ALIGN RIGHT"
    CENTER = "ALIGN CENTER"
    TOP = "ALIGN TOP"
    BOTTOM = "ALIGN BOTTOM"

    NORMAL = "GUI NORMAL"
    HOVER = "GUI HOVER"
    PRESSED = "GUI PRESSED"

    def __init__(self):
        self.child = []
        self.parent = None

        self.skin = Skin()

        self._position = Vec2d(0, 0)
        self.absolute_position = Vec2d(0, 0)
        self.visible = True
        self.size = Vec2d(0, 0)
        self.color = None
        self.background_color = None
        self.border_color = 0

        self.padding = 0
        self.margin = 0
        self.border = 0

        self.state = Gui.NORMAL
        self._rect = pygame.Rect(self.absolute_position, self.size)
        self._regenerate_surface = True
        self._surface = None

    def add(self, child):
        self.child.append(child)
        child.parent = self
        child.recalculate_absolute_position()

    def remove(self, child):
        self.child.remove(child)
        child.parent = None
        child.recalculate_absolute_position()

    def update(self):
        for c in self.child:
            c.update()

    def create_surface(self):
        self._surface = pygame.Surface(self._rect.size, pygame.SRCALPHA, 32)
        if self.background_color:
            self._surface.fill(self.background_color)

    def render(self, target):
        self.renderSelf(target)
        self.renderChild(target)
        #self.surface.fill(ALPHA_COLOR)
        #self.surface.set_colorkey(ALPHA_COLOR)

    def renderSelf(self, target):
        pass

    def renderChild(self, target):
        for c in self.child:
            c.renderSelf(target)

    def recalculate_absolute_position(self):
        self.absolute_position = Vec2d(self._position)
        if self.parent:
            self.absolute_position += self.parent.absolute_position

        self._rect = pygame.Rect(self.absolute_position, self.size)

    def _get_position(self):
        return self._position
    def _set_position(self, position):
        self._position = Vec2d(position)
        self.recalculate_absolute_position()

    position = property(_get_position, _set_position, None, "gets or sets the position of GUI")

class Label(Gui):

    def __init__(self):
        Gui.__init__(self)

        self._text = ""
        self._font_size = 10
        self.alignment_x = Gui.CENTER
        self.alignment_y = Gui.CENTER

    def create_surface(self):
        Gui.create_surface(self)

        if self._text:
            self.skin.drawText(
                self._surface,
                None,
                self._text,
                self.color,
                self._font_size,
                self.alignment_x,
                self.alignment_y
            )

        self._regenerate_surface = False


    def renderSelf(self, target):
        if self._regenerate_surface:
            self.create_surface()

        target.blit(self._surface, self._rect)

    def _get_text(self):
        return self._text

    def _set_text(self, text):
        if self._text != text:
            self._regenerate_surface = True
            self._text = text

    text = property(_get_text, _set_text, None, "gets or sets the text of GUI")

    def _get_font_size(self):
        return self._font_size

    def _set_font_size(self, font_size):
        if self._font_size != font_size:
            self._regenerate_surface = True
            self._font_size = font_size

    font_size = property(_get_font_size, _set_font_size, None, "gets or sets the font_size of GUI")

class Panel(Gui):
    def __init__(self):
        Gui.__init__(self)

    def render(self, target):
        pass


class HpBar(Gui):
    def __init__(self):
        Gui.__init__(self)
        self._value = 1
        self._max = 1
        self.percent = 1.0
        self.text_color = None

    def create_surface(self):
        Gui.create_surface(self)
        percent = self._value / self._max

        deflate = self.border * 2
        bar_width = (self.size.x - deflate) * percent
        if (bar_width <= 0): bar_width = 0


        hp_bar_rect = self._surface.get_rect().inflate(-deflate, -deflate)
        hp_bar_rect.width = bar_width
        hp_bar_rect.topleft = (self.border, self.border)
        self._surface.fill(self.color, hp_bar_rect)

        # TODO: Standardize border
        #self.skin.drawBorder(self._surface, self.background_color, self.border)

    def renderSelf(self, target):
        if self._regenerate_surface:
            self.create_surface()

        target.blit(self._surface, self._rect)


    def _get_value(self):
        return self._value

    def _set_value(self, value):
        if self._value != value:
            self._regenerate_surface = True
            self._value = value

    value = property(_get_value, _set_value, None, "gets or sets the value of bar")

    def _get_max(self):
        return self._max

    def _set_max(self, max_value):
        if self._max != max_value:
            self._regenerate_surface = True
            self._max = max_value

    max = property(_get_max, _set_max, None, "gets or sets the max value of bar")



class Button(Label):
    def __init__(self):
        Label.__init__(self)
        self.pressed = False

    def create_surface(self):
        Label.create_surface(self)

        color = self.color

        if self.state == Gui.HOVER:
            color = pygame.Color(0, 255, 0)
        elif self.state == Gui.PRESSED:
            color = pygame.Color(255, 0, 0)

        self.skin.drawBorder(self._surface, color, self.border)

    def renderSelf(self, target):
        if self._regenerate_surface:
            self.create_surface()

        target.blit(self._surface, self._rect)

class IconButton(Button):
    def __init__(self):
        Button.__init__(self)



class Skin(object):
    def __init__(self):
        pass

    ## TODO: Do sometihng to this 2 external methods
    ## It cant support black
    @staticmethod
    def textHollow(font, message, fontcolor):
        notcolor = [c ^ 0xFF for c in fontcolor]
        base = font.render(message, 0, fontcolor, notcolor)
        size = base.get_width() + 2, base.get_height() + 2
        img = pygame.Surface(size, 16)
        img.fill(notcolor)
        base.set_colorkey(0)
        img.blit(base, (0, 0))
        img.blit(base, (2, 0))
        img.blit(base, (0, 2))
        img.blit(base, (2, 2))
        base.set_colorkey(0)
        base.set_palette_at(1, notcolor)
        img.blit(base, (1, 1))
        img.set_colorkey(notcolor)
        return img

    @staticmethod
    def textOutline(font, message, fontcolor, outlinecolor):
        base = font.render(message, 0, fontcolor)
        outline = Skin.textHollow(font, message, outlinecolor)
        img = pygame.Surface(outline.get_size(), 16)
        img.fill(ALPHA_COLOR)
        img.set_colorkey(ALPHA_COLOR)
        img.blit(base, (1, 1))
        img.blit(outline, (0, 0))
        return img

    def drawText(self,
                 surface,
                 rect,
                 text,
                 color,
                 font_size,
                 alignment_x,
                 alignment_y):


        font = pygame.font.Font(pygame.font.get_default_font(), font_size)
        #text_surface = font.render(text, 1, color)
        outlinecolor = pygame.Color(0, 0, 0);
        text_surface = Skin.textOutline(font, text, color, outlinecolor)

        label_rect = text_surface.get_rect()
        if not rect:
            rect = surface.get_rect()

        ## X Alignment
        if alignment_x is Gui.LEFT:
            label_rect.left = rect.left
        elif alignment_x is Gui.RIGHT:
            label_rect.right = rect.right
        else:
            label_rect.centerx = rect.centerx

        ## Y Alignment
        if alignment_y is Gui.TOP:
            label_rect.top = rect.top
        elif alignment_y is Gui.BOTTOM:
            label_rect.bottom = rect.bottom
        else:
            label_rect.centery = rect.centery

        surface.blit(text_surface, label_rect.topleft)

    def drawBorder(self,
                   surface,
                   color,
                   line_width):

        rect = surface.get_rect()
        deflate = line_width
        rect = rect.inflate(-deflate, -deflate)
        rect.topleft = (0, 0)

        pointlist = []
        pointlist.append(rect.topleft)
        pointlist.append(rect.topright)
        pointlist.append(rect.bottomright)
        pointlist.append(rect.bottomleft)

        pygame.draw.lines(surface, color, True, pointlist, line_width)


